package com.pdool.room.fight;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.pdool.common.constants.Constant;
import com.pdool.common.constants.MsgId;
import com.pdool.common.dict.CardEffectVo;
import com.pdool.common.dict.CardInfoConfigVo;
import com.pdool.common.msg.fight.AreaFightChangeSTC;
import com.pdool.common.msg.fight.Back2HandCardSTC;
import com.pdool.common.msg.fight.CardEffectSTC;
import com.pdool.room.context.RoleFightInfo;
import com.pdool.room.context.RoomContext;
import com.pdool.room.dict.BasePropConfig;
import com.pdool.room.dict.CardConfig;
import com.pdool.room.fight.area.AreaInfo;
import com.pdool.room.fight.area.FightAreaInfo;
import com.pdool.room.fight.effect.CardFightVo;
import com.pdool.room.fight.effect.EffectFightVo;
import com.pdool.room.mgr.RoomMgr;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

@Component
@Slf4j
public class ActionUtil {
    static ActionUtil instance;

    public ActionUtil() {
        instance = this;
    }

    public static ActionUtil getInstance() {
        return instance;
    }

    @Resource
    BasePropConfig basePropConfig;
    @Autowired
    CardConfig cardConfig;

    public void action1_area(FightAreaInfo areaInfo, int num, RoomContext roomContext) {
        areaInfo.setAddFight(areaInfo.getAddFight() + num);
        calcAreaFight(areaInfo.getRoleId(),areaInfo.getAreaId(), roomContext);
    }
    public void action21_area(FightAreaInfo areaInfo, int num, RoomContext roomContext) {
        areaInfo.setTmpFight(areaInfo.getTmpFight() + num);
        calcAreaFight(areaInfo.getRoleId(),areaInfo.getAreaId(), roomContext);
    }


    public void action2_area(FightAreaInfo areaInfo,RoomContext roomContext) {
        Long sumFight = areaInfo.getSumFight();
        Long addFight = areaInfo.getAddFight();

        areaInfo.setAddFight(sumFight + addFight);
        calcAreaFight(areaInfo.getRoleId(),areaInfo.getAreaId(), roomContext);

    }

    //  1 战力+-
    public void action1(CardFightVo cardFightVo, EffectFightVo effectFightVo, RoomContext roomContext) {
//        log.error("roleId {} areaId {}   cardId  {} cur  {}  add {}",cardFightVo.getRoleId(),cardFightVo.getAreaId(), cardFightVo.getCardId(),cardFightVo.getFight(),effectFightVo.getEffectConfigVo().getActionNum());
        cardFightVo.setFight(cardFightVo.getFight() + effectFightVo.getEffectConfigVo().getActionNum(),roomContext);
        //  计算区域战力
        int areaId = cardFightVo.getAreaId();

        calcAreaFight(cardFightVo.getRoleId(), areaId, roomContext);

        sendCardEffect(roomContext, effectFightVo.getEffectConfigVo(), cardFightVo);

    }

    //  2 战力翻倍
    public void action2(CardFightVo cardFightVo, RoomContext roomContext) {
        cardFightVo.setFight(cardFightVo.getFight() * 2,roomContext);

        //  计算区域战力
        int areaId = cardFightVo.getAreaId();
        calcAreaFight(cardFightVo.getRoleId(),areaId, roomContext);
    }
    public void action15(CardFightVo cardFightVo,List<Object> targetList, RoomContext roomContext) {
        if (targetList.isEmpty()){
            return;
        }
        cardFightVo.setFight(cardFightVo.getFight() * 2,roomContext,true);

        //  计算区域战力
        int areaId = cardFightVo.getAreaId();
        calcAreaFight(cardFightVo.getRoleId(),areaId, roomContext);
    }
    //  3 移动到指定战场 todo
    public void action3(CardFightVo cardFightVo) {
//        cardFightVo.setAreaId();
    }

    //  5 回到手牌（初始）
    public void action5(CardFightVo cardFightVo, RoomContext roomContext) {
        Back2HandCardSTC.Builder builder = Back2HandCardSTC.newBuilder();
        builder.setAreaId(cardFightVo.getAreaId());
        builder.setOwnerId(cardFightVo.getRoleId());
        builder.setCardId(cardFightVo.getCardId());
        //  移除区域内的卡牌
        removeFromArea(cardFightVo, roomContext);
        //  回到手牌
        cardFightVo.setAreaId(Constant.AREA_HAND);
        cardFightVo.setRound(-1);

        RoleFightInfo roleFightInfo = roomContext.getMemberMap().get(cardFightVo.getRoleId());
        roleFightInfo.getHandAreaInfo().getCardList().add(cardFightVo);
        //  推送
        FightUtil.getInstance().pushHandCardChange(cardFightVo.getRoleId(), roleFightInfo.getHandAreaInfo().getCardList());

        RoomMgr.getInstance().sendMsg2Room(roomContext, MsgId.PUSH_CARD_BACK_HAND, builder.build());


    }

    //    7 将指定卡牌移到场外
    public void action7(CardFightVo cardFightVo, RoomContext roomContext) {
        cardFightVo.setValid(false);
        removeFromArea(cardFightVo, roomContext);
    }

    //  8 消耗锁定（0）
    public void action8(Object target, int num) {
        if (target instanceof CardFightVo) {
            CardFightVo cardFightVo = (CardFightVo) target;
            cardFightVo.setCost(num);
        } else if (target instanceof RoleFightInfo) {
            //  TODO 消耗锁定
        }

    }

    //  10 增加能量
    public void action10(long roleId, RoomContext roomContext, int num) {
        RoleFightInfo roleFightInfo = roomContext.getMemberMap().get(roleId);
        roleFightInfo.setAddEnergy(roleFightInfo.getAddEnergy() + num);
    }

    // 11- 针对当前卡-存在单位数量*action对应参数
    public void action11(CardFightVo cardFightVo, List<Object> targetList, int num, RoomContext roomContext) {
        if (targetList.isEmpty()){
            return;
        }
        int areaId = cardFightVo.getAreaId();
        int count = targetList.size();
        int addFight = count * num;
//        log.error("roleId {}  areaId {}  cardId  {} cur  {}  add {}",cardFightVo.getRoleId(),cardFightVo.getAreaId(), cardFightVo.getCardId(),cardFightVo.getFight(),addFight);
        cardFightVo.setFight(cardFightVo.getFight() + addFight,roomContext);
        calcAreaFight(cardFightVo.getRoleId(), areaId, roomContext);

    }

    // 12- 你在此区域放置一张卡牌后，会向另一区域添加1张复制牌
    public void action12(CardFightVo cardFightVo, List<Object> targetList, RoomContext roomContext) {
        CardFightVo copy = new CardFightVo();
        BeanUtil.copyProperties(cardFightVo, copy);
        AreaInfo areaInfo = (AreaInfo) targetList.get(0);
        copy.setAreaId(areaInfo.getAreaId());
        copy.setFakeCard(true);


        RoleFightInfo roleFightInfo = roomContext.getMemberMap().get(cardFightVo.getRoleId());
        roleFightInfo.getCardList().add(copy);

        areaInfo.getCardList().add(copy);
    }

    public void action13(List<Object> targetList, RoomContext roomContext) {

    }
    public void action14(CardFightVo cardFightVo, List<Object> targetList, int num, RoomContext roomContext) {
        if (targetList.size() == 0){
            return;
        }
        int areaId = cardFightVo.getAreaId();
        cardFightVo.setFight(cardFightVo.getFight() + num,roomContext,true);
        calcAreaFight(cardFightVo.getRoleId(), areaId, roomContext);

    }
    public void sendCardEffect(RoomContext roomContext, CardEffectVo effectVo, CardFightVo cardFightVo) {
        CardEffectSTC.Builder builder = CardEffectSTC.newBuilder();
        builder.setOwnerId(cardFightVo.getRoleId());
        builder.setAreaId(cardFightVo.getAreaId());
        builder.setCardId(cardFightVo.getCardId());
        builder.setEffectId(effectVo.getEffectId());
        int num = effectVo.getActionNum();
        if (effectVo.getExAction() == Constant.EX_ACTION_TARGET_1) {
            builder.setFightChange(num);
        } else {
            builder.setFightMult(num);
        }
        RoomMgr.getInstance().sendMsg2Room(roomContext, MsgId.PUSH_CARD_FIGHT_CHANGE, builder.build());
    }

    //-----------------------------------------------------------------------------------------------------------
    //从战场移除
    public void removeFromArea(CardFightVo cardFightVo, RoomContext roomContext) {

        int areaId = cardFightVo.getAreaId();
        if (areaId == -1){
            return;
        }
        RoleFightInfo roleFightInfo = roomContext.getMemberMap().get(cardFightVo.getRoleId());

        //  移除区域内的卡牌
        FightAreaInfo areaInfo = roleFightInfo.getAreaInfoList().get(areaId);
        areaInfo.getCardList().remove(cardFightVo);

        calcAreaFight(cardFightVo.getRoleId(), areaId, roomContext);
    }

    public Long calcAreaFight(long roleId,int areaId, RoomContext roomContext) {
        if (areaId == -1) {
            return 0L;
        }
        RoleFightInfo roleFightInfo = roomContext.getMemberMap().get(roleId);
        FightAreaInfo areaInfo = roleFightInfo.getAreaInfoList().get(areaId);
        Long fight = 0L;
        List<CardFightVo> cardList = areaInfo.getCardList();
        for (CardFightVo cardFightVo : cardList) {
            fight += cardFightVo.getFight() + cardFightVo.getTmpFight();
        }

        fight += areaInfo.getAddFight();
        areaInfo.setSumFight(fight);

        AreaFightChangeSTC.Builder builder = AreaFightChangeSTC.newBuilder();
        builder.setAreaId(areaInfo.getAreaId());
        builder.setOwnerId(areaInfo.getRoleId());
        builder.setFight(areaInfo.getSumFight());

        RoomMgr.getInstance().sendMsg2Room(roomContext, MsgId.PUSH_AREA_FIGHT_CHANGE, builder.build());
//        log.error(" fight    ------------->roleId: {}  areaId:  {}  fight: {}",roleId,areaId,fight);
        return fight;
    }

    public void action13_area(AreaInfo areaInfo, RoomContext roomContext) {

        String value = basePropConfig.getByKey(Constant.PROP_CALL_LIST).getValue();

        String[] split = value.split(Constant.SPLIT_COMMA);
        int rand = RandomUtil.randomInt(split.length);
        int cardId = Integer.parseInt(split[rand]);

        CardInfoConfigVo cardConfig = this.cardConfig.getByKey(cardId);

        CardFightVo cardFightVo = new CardFightVo();

        cardFightVo.setCardId(cardId);
        cardFightVo.setFight(cardConfig.getFight(),roomContext);
        cardFightVo.setCardType(cardConfig.getCardType());
        cardFightVo.setFakeCard(true);
        cardFightVo.setCost(cardConfig.getCost());
        if (areaInfo instanceof FightAreaInfo) {
            cardFightVo.setAreaId(areaInfo.getAreaId());
            cardFightVo.setRound(roomContext.getCurRound());
        }
        int pos = roomContext.getMemberMap().get(areaInfo.getRoleId()).getPos();
        cardFightVo.setPos(pos);
        areaInfo.getCardList().add(cardFightVo);
    }

    public void action21(CardFightVo cardFightVo, EffectFightVo effectFightVo, RoomContext roomContext) {
        //        log.error("roleId {} areaId {}   cardId  {} cur  {}  add {}",cardFightVo.getRoleId(),cardFightVo.getAreaId(), cardFightVo.getCardId(),cardFightVo.getFight(),effectFightVo.getEffectConfigVo().getActionNum());
        cardFightVo.setTmpFight(cardFightVo.getTmpFight() + effectFightVo.getEffectConfigVo().getActionNum(),roomContext,true);
        //  计算区域战力
        int areaId = cardFightVo.getAreaId();
        calcAreaFight(cardFightVo.getRoleId(), areaId, roomContext);
        sendCardEffect(roomContext, effectFightVo.getEffectConfigVo(), cardFightVo);
    }

    // 23-  针对当前卡增加临时战力-存在单位数量*action对应参数 （每回合开始时重置，针对多轮计算）
    public void action23(CardFightVo cardFightVo, List<Object> targetList, int num, RoomContext roomContext) {
        if (targetList.isEmpty()){
            return;
        }
        int areaId = cardFightVo.getAreaId();
        int count = targetList.size();
        int addFight = count * num;
//        log.error("roleId {}  areaId {}  cardId  {} cur  {}  add {}",cardFightVo.getRoleId(),cardFightVo.getAreaId(), cardFightVo.getCardId(),cardFightVo.getFight(),addFight);
        cardFightVo.setTmpFight(cardFightVo.getTmpFight() + addFight,roomContext,true);
        calcAreaFight(cardFightVo.getRoleId(), areaId, roomContext);    }
    //  针对当前卡增加临时战力-存在则增加action对应参数 （每回合开始时重置，针对多轮计算）
    public void action24(CardFightVo cardFightVo, List<Object> targetList, Integer actionNum, RoomContext roomContext) {
        if (targetList.isEmpty()){
            return;
        }
        int areaId = cardFightVo.getAreaId();
//        log.error("roleId {}  areaId {}  cardId  {} cur  {}  add {}",cardFightVo.getRoleId(),cardFightVo.getAreaId(), cardFightVo.getCardId(),cardFightVo.getFight(),addFight);
        cardFightVo.setTmpFight(cardFightVo.getTmpFight() + actionNum,roomContext,true);
        calcAreaFight(cardFightVo.getRoleId(), areaId, roomContext);
    }
}
